//
// graph.cpp for 202loi in /home/faucon_l//Work/Tek2/maths/202loi
//
// Made by leo faucon
// Login   <faucon_l@epitech.net>
//
// Started on  Fri Feb 25 16:58:26 2011 leo faucon
// Last update Sat Apr  9 17:07:38 2011 leo faucon
//

#include	"SDL_graph.hpp"

SDL_graph::SDL_graph(SDL_Surface * _ecran_)
{
  ecran = _ecran_;
  initCouleurs();
}

SDL_graph::~SDL_graph()
{
  SDL_FreeSurface(ecran);
}

void	SDL_graph::initCouleurs(void)
{
  couleurs[C_NOIR]          = SDL_MapRGB(ecran->format, 0x00, 0x00, 0x00);
  couleurs[C_BLEU_FONCE]    = SDL_MapRGB(ecran->format, 0x00, 0x00, 0x80);
  couleurs[C_VERT_FONCE]    = SDL_MapRGB(ecran->format, 0x00, 0x80, 0x00);
  couleurs[C_CYAN_FONCE]    = SDL_MapRGB(ecran->format, 0x00, 0x80, 0x80);
  couleurs[C_ROUGE_FONCE]   = SDL_MapRGB(ecran->format, 0x80, 0x00, 0x00);
  couleurs[C_MAGENTA_FONCE] = SDL_MapRGB(ecran->format, 0x80, 0x00, 0x80);
  couleurs[C_OCRE]          = SDL_MapRGB(ecran->format, 0x80, 0x80, 0x00);
  couleurs[C_GRIS_CLAIR]    = SDL_MapRGB(ecran->format, 0xC0, 0xC0, 0xC0);
  couleurs[C_GRIS]          = SDL_MapRGB(ecran->format, 0x80, 0x80, 0x80);
  couleurs[C_BLEU]          = SDL_MapRGB(ecran->format, 0x00, 0x00, 0xFF);
  couleurs[C_VERT]          = SDL_MapRGB(ecran->format, 0x00, 0xFF, 0x00);
  couleurs[C_CYAN]          = SDL_MapRGB(ecran->format, 0x00, 0xFF, 0xFF);
  couleurs[C_ROUGE]         = SDL_MapRGB(ecran->format, 0xFF, 0x00, 0x00);
  couleurs[C_MAGENTA]       = SDL_MapRGB(ecran->format, 0xFF, 0x00, 0xFF);
  couleurs[C_JAUNE]         = SDL_MapRGB(ecran->format, 0xFF, 0xFF, 0x00);
  couleurs[C_BLANC]         = SDL_MapRGB(ecran->format, 0xFF, 0xFF, 0xFF);
}

void	SDL_graph::actualiser(void)
{
  SDL_Flip(ecran);
}

int	SDL_graph::attendreTouche(void)
{
  SDL_Event event;

  while (1)
    {
      SDL_WaitEvent(&event);
      if (event.type == SDL_QUIT)
	return (-1);
      else if (event.type == SDL_KEYDOWN)
	return (event.key.keysym.sym);
    }
}

void	SDL_graph::setPixel(int x, int y, Uint32 coul)
{
  *((Uint32*)(ecran->pixels) + x + y * ecran->w) = coul;
}

void	SDL_graph::setPixelVerif(int x, int y, Uint32 coul)
{
  if (x >= 0 && x < ecran->w &&
      y >= 0 && y < ecran->h)
    setPixel(x, y, coul);
}

void	SDL_graph::ligne_graphHorizontale(int x, int y, int w, Uint32 coul)
{
  SDL_Rect r;

  r.x = x;
  r.y = y;
  r.w = w;
  r.h = 1;

  SDL_FillRect(ecran, &r, coul);
}

void	SDL_graph::ligne_graphVerticale(int x, int y, int h, Uint32 coul)
{
  SDL_Rect r;

  r.x = x;
  r.y = y;
  r.w = 1;
  r.h = h;

  SDL_FillRect(ecran, &r, coul);
}

void	SDL_graph::effacerEcran(void)
{
  SDL_FillRect(ecran, NULL, couleurs[C_NOIR]);
}

void	SDL_graph::echangerEntiers(int* x, int* y)
{
  int t = *x;
  *x = *y;
  *y = t;
}

void	SDL_graph::ligne_graph(int x1, int y1, int x2, int y2, Uint32 coul)
{
  int d, dx, dy, aincr, bincr, xincr, yincr, x, y;

  if (abs(x2 - x1) < abs(y2 - y1))
    {
      if (y1 > y2)
	{
	  echangerEntiers(&x1, &x2);
	  echangerEntiers(&y1, &y2);
	}
      xincr = x2 > x1 ? 1 : -1;
      dy = y2 - y1;
      dx = abs(x2 - x1);
      d = 2 * dx - dy;
      aincr = 2 * (dx - dy);
      bincr = 2 * dx;
      x = x1;
      y = y1;
      setPixelVerif(x, y, coul);
      for (y = y1+1; y <= y2; ++y)
	{
	  if (d >= 0)
	    {
	      x += xincr;
	      d += aincr;
	    }
	  else
	    d += bincr;
	  setPixelVerif(x, y, coul);
	}
    }
  else
    {
      if (x1 > x2)
	{
	  echangerEntiers(&x1, &x2);
	  echangerEntiers(&y1, &y2);
	}
      yincr = y2 > y1 ? 1 : -1;
      dx = x2 - x1;
      dy = abs(y2 - y1);
      d = 2 * dy - dx;
      aincr = 2 * (dy - dx);
      bincr = 2 * dy;
      x = x1;
      y = y1;
      setPixelVerif(x, y, coul);
      for (x = x1+1; x <= x2; ++x)
	{
	  if (d >= 0)
	    {
	      y += yincr;
	      d += aincr;
	    }
	  else
	    d += bincr;
	  setPixelVerif(x, y, coul);
	}
    }
}
